package cn.com.bluemoon.daps.model.controller;


import cn.com.bluemoon.daps.api.sys.RemoteSystemDatasourceService;
import cn.com.bluemoon.daps.common.datascope.BmPermission;
import cn.com.bluemoon.daps.common.domain.ResultBean;
import cn.com.bluemoon.daps.common.enums.BmStatus;
import cn.com.bluemoon.daps.common.enums.DatabaseType;
import cn.com.bluemoon.daps.model.dto.DapDataModelTableDto;
import cn.com.bluemoon.daps.model.dto.ModelTableInfoDto;
import cn.com.bluemoon.daps.model.dto.score.TableScoreDto;
import cn.com.bluemoon.daps.model.entity.*;
import cn.com.bluemoon.daps.model.service.*;
import cn.com.bluemoon.daps.model.vo.score.SearchTableScoreVo;
import cn.com.bluemoon.daps.system.entity.DapSystemDatasource;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@Slf4j
@RequestMapping("")
@Api(tags = {"表结构评分"})
public class DapDataModelTableScoreController {

    @Resource
    DapDataModelTableScoreRuleService dapDataModelTableScoreRuleService;

    @Resource
    DapDataModelService dapDataModelService;

    @Resource
    DapDataModelTableService dapDataModelTableService;

    @Resource
    RemoteSystemDatasourceService remoteSystemDatasourceService;

    @Resource
    DapDataModelTableFieldService dapDataModelTableFieldService;

    @Resource
    DapDataModelSubordinateKeyService dapDataModelSubordinateKeyService;


    @GetMapping("rule/list")
    @ApiOperation("评分规则列表")
    @BmPermission(value = "model:table:info", name = "评分规则列表")
    @ApiResponses(value = {@ApiResponse(code = 500, message = "错误原因信息", response = String.class),
            @ApiResponse(code = 200, message = "ok", responseContainer = "List", response = DapDataModelTableScoreRule.class)})
    public ResultBean<IPage<DapDataModelTableScoreRule>> getRuleList(@RequestParam("pageNum") @ApiParam("当前页码") Integer pageNum,
                                                                     @RequestParam("pageSize") @ApiParam("显示数量") Integer pageSize){

        Page<DapDataModelTableScoreRule> page = new Page<>(pageNum, pageSize);
        IPage<DapDataModelTableScoreRule> pageList = dapDataModelTableScoreRuleService
                .getBaseMapper().selectPage(page, new LambdaUpdateWrapper<DapDataModelTableScoreRule>().
                eq(DapDataModelTableScoreRule::getBmStatus, BmStatus.ON.getCode()));
        return ResultBean.ok(pageList);

    }

    @PostMapping("table/score/list")
    @ApiOperation("模型表得分详情列表")
    @BmPermission(value = "model:table:info", name = "得分列表")
    @ApiResponses(value = {@ApiResponse(code = 500, message = "错误原因信息", response = String.class),
            @ApiResponse(code = 200, message = "ok", responseContainer = "list", response = TableScoreDto.class)})
    public ResultBean<IPage<TableScoreDto>> tableScoreList(@RequestBody @Valid SearchTableScoreVo vo) {

        // 获得表分页列表
        IPage<TableScoreDto> pageList = dapDataModelService.getTableScoreList(vo);
        // 获得表详情
        List<TableScoreDto> records = pageList.getRecords();
        List<String> ids = records.stream().map(TableScoreDto::getTableId).collect(Collectors.toList());
        if (ids.isEmpty()) {
            return ResultBean.error("暂无数据");
        }
        // 获取表信息
        List<DapDataModelTable> collect = dapDataModelTableService.getBaseMapper().selectBatchIds(ids);
        // 过滤掉删除的数据
        List<DapDataModelTable> tables = collect.stream().filter(t -> t.getBmStatus().equals(BmStatus.ON)).collect(Collectors.toList());
        // 获取字段信息
        List<DapDataModelTableField> fields = dapDataModelTableFieldService.getBaseMapper().selectList(new LambdaQueryWrapper<DapDataModelTableField>()
                .in(DapDataModelTableField::getModelTableId, ids).eq(DapDataModelTableField::getBmStatus, BmStatus.ON.getCode()));
        // 获取索引信息
        List<DapDataModelSubordinateKey> keys = dapDataModelSubordinateKeyService.getBaseMapper().selectList(new LambdaQueryWrapper<DapDataModelSubordinateKey>()
                .in(DapDataModelSubordinateKey::getModelTableId, ids).eq(DapDataModelSubordinateKey::getBmStatus, BmStatus.ON.getCode()));
        // 封装数据
        List<DapDataModelTableDto> tableList = new ArrayList<>();
        tables.forEach(t -> {
            DapDataModelTableDto dto = new DapDataModelTableDto();
            dto.setTableId(t.getId());
            dto.setEngName(t.getEngName());
            dto.setName(t.getName());
            // 当前表的字段
            List<DapDataModelTableField> fieldList = fields.stream().filter(f -> f.getModelTableId().equals(t.getId())).collect(Collectors.toList());
            dto.setFieldList(fieldList);
            // 当前表的索引
            List<DapDataModelSubordinateKey> keyList = keys.stream().filter(k -> k.getModelTableId().equals(t.getId())).collect(Collectors.toList());
            dto.setKeyList(keyList);
            tableList.add(dto);
        });
        List<TableScoreDto> tableScore = dapDataModelTableScoreRuleService.getTableScore(tableList, pageList.getRecords());
        pageList.setRecords(tableScore);
        return ResultBean.ok(pageList);
    }

    @GetMapping("single/table/score")
    @ApiOperation("单个表得分详情")
    @BmPermission(value = "model:table:info", name = "得分详情")
    @ApiResponses(value = {@ApiResponse(code = 500, message = "错误原因信息", response = String.class),
            @ApiResponse(code = 200, message = "ok", responseContainer = "List", response = DapDataModelTableScoreRule.class)})
    public ResultBean<List<DapDataModelTableScoreRule>> tableScore(@RequestParam("modelId")@ApiParam("模型id") String modelId,
                                                                   @RequestParam("tableId")@ApiParam("表id") String tableId){
        // 查询当前模型是否支持评分功能
        DapDataModel dapDataModel = dapDataModelService.getBaseMapper().selectById(modelId);
        ResultBean<DapSystemDatasource> datasource = remoteSystemDatasourceService.getDatasource(dapDataModel.getDataSourceId());
        if (datasource.getCode() == 200 && datasource.getContent() != null){
            if(!datasource.getContent().getDatabaseType().equals(DatabaseType.MYSQL)){
                return ResultBean.error(String.format("%模型不支持评分功能", dapDataModel.getName()));
            }
        }else {
            return ResultBean.error(datasource.getMsg());
        }
        // 获得表信息
        ModelTableInfoDto tableInfo = dapDataModelTableFieldService.getTableInfo(tableId);
        if(tableInfo == null || tableInfo.getFieldList().isEmpty()){
            return ResultBean.error("表结构为空，无法进行表评分");
        }
        // 获得索引信息
        List<DapDataModelSubordinateKey> keys = dapDataModelSubordinateKeyService.getBaseMapper().selectList(new LambdaQueryWrapper<DapDataModelSubordinateKey>()
                .eq(DapDataModelSubordinateKey::getModelTableId, tableId).eq(DapDataModelSubordinateKey::getBmStatus, BmStatus.ON.getCode()));
        DapDataModelTableDto dto = new DapDataModelTableDto();
        BeanUtils.copyProperties(tableInfo, dto);
        dto.setKeyList(keys);
        List<DapDataModelTableScoreRule> ruleList = dapDataModelTableScoreRuleService.singleTableScore(dto);
        double sum = ruleList.stream().map(DapDataModelTableScoreRule::getScore).mapToDouble(Double::valueOf).sum();
        return ResultBean.ok(ruleList).addMoreData("totalScore", sum);
    }

}
